home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
workbench werkzeuge
/
bildschirmschoner
/
snowblank
/
source
/
snow
/
blank.c
next >
Wrap
C/C++ Source or Header
|
1996-04-07
|
6KB
|
265 lines
/* --------------------------------------------------------------------
*
* A christmas blanker inspired by xsnow
*
* initialization/cleanup code copied from the dragon module
* (dragon module: (C)Alexander Kneer and Michael D. Bayne)
*
* -------------------------------------------------------------------- */
#include <exec/memory.h>
#include <math.h>
#include <stdlib.h>
#include "/includes.h"
#define STAGES 2 /* Number of different shapes */
#define BLANKDELAY 100 /* This many snowflakes are displayed before
* we check if to continue blanking */
#define COUNTLIMIT 6 /* max. number of moves in one direction */
#define COUNTMIN 1 /* min. number of moves in one direction */
/* random generation function macros */
#define COUNTFUNC RangeRand(COUNTLIMIT-COUNTMIN)+COUNTMIN
#define DXFUNC RangeRand(5)-2;
#define DYFUNC RangeRand(2)+1;
typedef enum { false, true } bool;
bool BIGFLAKES;
int NUMSNOW;
bool COLLECT;
int patx[10] = { -1,-1, 1, 1, 0 , -1, 1, 0, 0, 0 };
int paty[10] = { -1, 1,-1, 1, 0 , 0, 0, 1,-1, 0 };
int *collect;
typedef struct
{ int x,y; /* The current coordinates */
int dx,dy; /* Movement direction is (dx,dy) */
int count; /* How long to keep direction dx */
int stage; /* STAGES different shapes */
} snowflake;
Triplet *ColorTable = 0L;
#define PR_FLAKE 0
#define PR_BIG 2
#define PR_COLLECT 4
#define PR_MODE 6
VOID Defaults( PrefObject *Prefs )
{
Prefs[PR_FLAKE].po_Level = 200;
Prefs[PR_BIG].po_Level = 1;
Prefs[PR_COLLECT].po_Level = 1;
Prefs[PR_MODE].po_ModeID = getTopScreenMode();
}
/* Remove a single snowflake's image from the screen */
__inline void undraw(snowflake *flake, struct RastPort *rp)
{
if (BIGFLAKES)
{
int *startx = patx + 5*(flake->stage);
int *starty = paty + 5*(flake->stage);
int i;
SetAPen(rp,0);
for (i=0; i<5; i++)
{ WritePixel(rp,flake->x+(*startx),flake->y+(*starty));
startx++;
starty++;
}
}
else
{
SetAPen(rp,0);
WritePixel(rp,flake->x,flake->y);
}
}
/* Draw a single snowflake's image to the screen */
__inline void draw(snowflake *flake, struct RastPort *rp)
{
if (BIGFLAKES)
{
int *startx = patx + 5*(flake->stage);
int *starty = paty + 5*(flake->stage);
int i;
SetAPen(rp,1);
for (i=0; i<5; i++)
{ WritePixel(rp,flake->x+(*startx),flake->y+(*starty));
startx++;
starty++;
}
}
else
{ SetAPen(rp,1);
WritePixel(rp,flake->x,flake->y);
}
}
/* change the position of a snowflake. If it leaves [0..width]x[0..height],
* generate a new one with coordinates (<random>,0) */
__inline void update(snowflake *curr, int width, int height, struct RastPort *rp)
{ bool gen_new;
int oldx = curr->x;
if (curr->count > 0)
{ curr->y = curr->y + curr->dy;
if (curr->y >= height-1)
{ gen_new = true;
}
else
{ curr->x = curr->x + curr->dx;
if (curr->x < 1 || curr->x >= width-1)
{ gen_new = true;
}
else
{ gen_new = false;
(curr->count)--;
if (curr->count <= 0)
{ curr->dx = DXFUNC;
curr->count = COUNTFUNC;
}
if (curr->stage)
{ curr->stage--;
}
else
{ curr->stage = STAGES-1;
}
}
}
}
/* do we have to compute a new flake? */
if (gen_new)
{ if (collect && curr->y > height-3)
{ collect[oldx]--;
if (collect[oldx]<height-20)
{ collect[oldx]=height-20;
}
curr->x = oldx;
curr->y = collect[oldx];
draw(curr,rp);
}
curr->x = RangeRand(width-2)+1;
curr->y = 1;
curr->dx = DXFUNC;
curr->dy = DYFUNC;
curr->count = COUNTFUNC;
curr->stage = RangeRand(STAGES);
}
}
LONG snow(struct Screen *scr, SHORT width, SHORT height)
{
unsigned int i;
LONG flg_end;
snowflake *flake,*curr;
int blankcount;
struct RastPort *rp = &(scr->RastPort);
/* initialize the snow array */
flake = malloc(NUMSNOW*sizeof(snowflake));
curr = flake;
for (i=0; i<NUMSNOW; i++)
{ curr->x = RangeRand(width-2)+1;
curr->y = RangeRand(height-2)+1;
curr->dx = DXFUNC;
curr->dy = DYFUNC;
curr->count = COUNTFUNC;
curr->stage = RangeRand(STAGES);
curr++;
}
/* and the collect array */
if (COLLECT)
{ collect = malloc(sizeof(int)*width);
for (i=0; i<width; i++)
{ collect[i] = height-2;
}
collect[0] = 0;
collect[width-1] = 0;
}
else
{ collect = NULL;
}
/* Update all snowflakes forever. Update includes removal from the screen,
* computation of new position, drawing on the screen */
blankcount = BLANKDELAY;
while (1)
{ curr = flake;
for (i=0; i<NUMSNOW; i++)
{ /* Remove curr's image */
undraw(curr,rp);
/* compute new position and appearance */
update(curr,width,height,rp);
/* and display it */
draw(curr,rp);
/* can we continue? */
if (!blankcount)
{ blankcount = BLANKDELAY;
flg_end = ContinueBlanking();
ScreenToFront(scr);
if (flg_end != OK)
{ free(flake);
if (collect) free(collect);
return flg_end;
}
}
else
{ blankcount--;
}
curr++;
}
}
return OK; /* just for the compiler */
}
LONG Blank( PrefObject *Prefs )
{
struct Screen *Scr;
struct Window *Wnd;
LONG RetVal;
BIGFLAKES = Prefs[PR_BIG].po_Level;
NUMSNOW = Prefs[PR_FLAKE].po_Level;
COLLECT = Prefs[PR_COLLECT].po_Level;
if( Scr = OpenScreenTags( NULL, SA_Depth, 1,
SA_Quiet, TRUE, SA_DisplayID, Prefs[PR_MODE].po_ModeID,
SA_Behind, TRUE, SA_Overscan, OSCAN_STANDARD,
TAG_DONE ))
{
SetRGB4(&( Scr->ViewPort ), 0, 0, 0, 0 );
ColorTable = RainbowPalette( Scr, 0L, 1L, 0L );
SetRGB4(&( Scr->ViewPort ), 1, 15, 15, 15 );
Wnd = BlankMousePointer( Scr );
do
RetVal = snow( Scr, Scr->Width, Scr->Height );
while( RetVal == OK );
UnblankMousePointer( Wnd );
RainbowPalette( 0L, ColorTable, 1L, 0L );
CloseScreen( Scr );
}
else
RetVal = FAILED;
return RetVal;
}